home *** CD-ROM | disk | FTP | other *** search
- From: dfs@doe.carleton.ca (David F. Skoll)
- Newsgroups: comp.sources.misc
- Subject: v17i004: remind - A replacement for calendar, Part02/04
- Message-ID: <1991Feb19.162802.16192@sparky.IMD.Sterling.COM>
- Date: 19 Feb 91 16:28:02 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: aa12cd2e e27052be e1256319 e257cbfc
-
- Submitted-by: David F. Skoll <dfs@doe.carleton.ca>
- Posting-number: Volume 17, Issue 4
- Archive-name: remind/part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 2 (of 4)."
- # Contents: calendar.c dorem.c main.c test.out
- # Wrapped by kent@sparky on Tue Feb 19 10:16:40 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'calendar.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'calendar.c'\"
- else
- echo shar: Extracting \"'calendar.c'\" \(13183 characters\)
- sed "s/^X//" >'calendar.c' <<'END_OF_FILE'
- X/***************************************************************/
- X/* */
- X/* CALENDAR.C */
- X/* */
- X/* Contains routines and data structures for producing a */
- X/* calendar from a reminder file. */
- X/* */
- X/* By David Skoll - 14 November 1990 */
- X/* */
- X/***************************************************************/
- X#include <stdio.h>
- X#ifndef NO_MALLOC_H
- X#include <malloc.h>
- X#endif
- X#include <ctype.h>
- X#include <string.h>
- X#ifndef UNIX
- X#include <stdlib.h>
- X#endif
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X#include "cache.h"
- X
- X/* Convert (monday-sunday) sequence to (sunday-saturday) */
- X#define DayOfWeek(julian) ((((julian) % 7) + 1) % 7)
- X
- X/* To center an item of length l in a field of length f, how many spaces? */
- X#define PreCenter(f, l) (((f)-(l))/2)
- X
- X/* How many spaces AFTEr the centered item? */
- X#define PostCenter(f, l) ((f)-(l)-((f)-(l))/2)
- X
- X/* Define the structure of a calendar entry */
- Xtypedef struct CalEntry_t {
- X int tim;
- X char *text, *current;
- X struct CalEntry_t *next;
- X} CalEntry;
- X
- X/* Have a main calendar entry for each weekday */
- XCalEntry entry[7];
- Xint used[7]; /* These hold the day of the month for corresponding
- X entry - 0 if not used */
- X
- X/* Static integers for various stuff */
- Xstatic int TotalWidth;
- X
- X/* Make function prototypes local - they're not used anywhere else */
- X#ifdef __STDC__
- XCalEntry *CreateCalEntry(int type);
- Xvoid AddCalEntry(CalEntry *e);
- Xvoid EmitOneCalendarLine(void);
- Xvoid InitCalendar(int m, int y);
- Xvoid FinishCalendar(void);
- Xvoid DoEntries(void);
- X#else
- XCalEntry *CreateCalEntry();
- Xvoid AddCalEntry();
- Xvoid EmitOneCalendarLine();
- Xvoid InitCalendar();
- Xvoid FinishCalendar();
- Xvoid DoEntries();
- X#endif
- X
- X/***************************************************************/
- X/* */
- X/* DoCalendar - main loop for the calendar command. */
- X/* */
- X/***************************************************************/
- X#ifndef __STDC__
- Xvoid DoCalendar()
- X#else
- Xvoid DoCalendar(void)
- X#endif
- X{
- X int y, m, d, init;
- X
- X TotalWidth = 7*CalWidth + 8;
- X
- X /* Move back until beginning of month */
- X FromJulian(JulianToday, &d, &m, &y);
- X JulianToday -= (d-1);
- X
- X init = 0;
- X InitCache();
- X while (Calendar) {
- X FromJulian(JulianToday, &d, &m, &y);
- X CurDay = d;
- X CurMon = m;
- X CurYear = y;
- X if (init == 0 || CurDay == 1) { InitCalendar(m, y); init = 1; }
- X DoEntries();
- X if (d == DaysInMonth(m, y)) Calendar--;
- X JulianToday++;
- X if (Calendar) ResetCache();
- X }
- X if (CurDay != DaysInMonth(CurMon, CurYear)) FinishCalendar();
- X DestroyCache();
- X FreeStackedOmits();
- X}
- X
- X/***************************************************************/
- X/* */
- X/* PrintChars: Print n of the specified character */
- X/* CopyChars: Copy n of the character to the output buffer */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid PrintChars(int n, int c)
- X#else
- Xvoid PrintChars(n, c)
- Xint n, c;
- X#endif
- X{
- X while(n--) putchar(c);
- X}
- X
- X#ifdef __STDC__
- Xchar *CopyChars(int n, int c, char *dst)
- X#else
- Xchar *CopyChars(n, c, dst)
- Xint n, c;
- Xchar *dst;
- X#endif
- X{
- X while(n--) *dst++ = (char) c;
- X return dst;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* InitCalendar */
- X/* Print the calendar header */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid InitCalendar(int m, int y)
- X#else
- Xvoid InitCalendar(m, y)
- Xint y, m;
- X#endif
- X{
- X int i;
- X
- X if (SimpleCalendar) return;
- X
- X for (i=0; i<7; i++) {
- X entry[i].next = NULL;
- X used[i] = 0;
- X }
- X
- X /* Emit the calendar title */
- X putchar('+');
- X PrintChars(TotalWidth-2, '-');
- X putchar('+');
- X putchar('\n');
- X sprintf(TmpBuf, "%s %d", MonthName[m], y);
- X putchar('|');
- X PrintChars(PreCenter(TotalWidth-2, strlen(TmpBuf)), ' ');
- X printf("%s", TmpBuf);
- X PrintChars(PostCenter(TotalWidth-2, strlen(TmpBuf)), ' ');
- X putchar('|');
- X putchar('\n');
- X putchar('+');
- X for (i=0; i<7; i++) {
- X PrintChars(CalWidth, '-');
- X putchar('+');
- X }
- X putchar('\n');
- X
- X /* Put the weekdays in */
- X /* Argh! Do sunday first, then take care of rest */
- X i = 6;
- X putchar('|');
- X PrintChars(PreCenter(CalWidth, strlen(DayName[i])), ' ');
- X printf(DayName[i]);
- X PrintChars(PostCenter(CalWidth, strlen(DayName[i])), ' ');
- X
- X for (i=0; i<6; i++) {
- X putchar('|');
- X PrintChars(PreCenter(CalWidth, strlen(DayName[i])), ' ');
- X printf(DayName[i]);
- X PrintChars(PostCenter(CalWidth, strlen(DayName[i])), ' ');
- X }
- X putchar('|');
- X putchar('\n');
- X putchar('+');
- X for (i=0; i<7; i++) {
- X PrintChars(CalWidth, '-');
- X putchar('+');
- X }
- X putchar('\n');
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FinishCalendar */
- X/* Just print a form feed. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid FinishCalendar(void)
- X#else
- Xvoid FinishCalendar()
- X#endif
- X{
- X if (SimpleCalendar) return;
- X putchar('\f');
- X}
- X
- X/***************************************************************/
- X/* */
- X/* DoEntries */
- X/* Create all the calendar entries for this week */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid DoEntries(void)
- X#else
- Xvoid DoEntries()
- X#endif
- X{
- X int i;
- X CalEntry *e;
- X
- X while (1) {
- X used[DayOfWeek(JulianToday)] = CurDay;
- X if (GetLine()) break;
- X i = ProcessLine();
- X if (i>0) if (e = CreateCalEntry(i)) AddCalEntry(e);
- X }
- X
- X /* Now figure out if we should print the calendar */
- X if ((DayOfWeek(JulianToday) == 6 ) || CurDay == DaysInMonth(CurMon, CurYear))
- X EmitOneCalendarLine();
- X if (CurDay == DaysInMonth(CurMon, CurYear)) FinishCalendar();
- X}
- X
- X/***************************************************************/
- X/* */
- X/* AddCalEntry */
- X/* Add a calendar entry for the appropriate weekday. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid AddCalEntry(CalEntry *e)
- X#else
- Xvoid AddCalEntry(e)
- XCalEntry *e;
- X#endif
- X{
- X CalEntry *curr, *prev;
- X
- X prev = &entry[DayOfWeek(JulianToday)];
- X curr = prev->next;
- X while (curr) {
- X if (e->tim == -1 || (e->tim >= curr->tim && curr->tim != -1)) {
- X prev = curr;
- X curr = prev->next;
- X } else {
- X prev->next = e;
- X e->next = curr;
- X break;
- X }
- X }
- X if (!curr) {
- X prev->next = e;
- X e->next = NULL;
- X }
- X}
- X
- X#ifdef __STDC__
- Xvoid CopyWord(char **src, char **dst, int l)
- X#else
- Xvoid CopyWord(src, dst, l)
- Xchar **src, **dst;
- Xint l;
- X#endif
- X{
- X while(**src && !isspace(**src) && l--) *(*dst)++ = *(*src)++;
- X}
- X
- X#ifdef __STDC__
- Xint WordLen(char *src)
- X#else
- Xint WordLen(src)
- Xchar *src;
- X#endif
- X{
- X int len = 0;
- X while (*src && !isspace(*src)) { len++; src++; }
- X return len;
- X}
- X/***************************************************************/
- X/* */
- X/* CreateCalEntry */
- X/* */
- X/* Allocates and creates a calendar entry. */
- X/* */
- X/* Type = 1: MSG type = 2: RUN */
- X/* */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- XCalEntry *CreateCalEntry(int type)
- X#else
- XCalEntry *CreateCalEntry(type)
- Xint type;
- X#endif
- X{
- X CalEntry *e;
- X char *s, *t;
- X int column, l;
- X enum Token_t tok;
- X
- X if (type == 1) tok = Msg_t; else tok = Run_t;
- X
- X if (!SimpleCalendar) {
- X e = (CalEntry *) malloc(sizeof(CalEntry));
- X
- X if (e == NULL) {
- X fprintf(stderr, "remind: Can't malloc to create calendar entry.\n");
- X exit(1);
- X }
- X e->next = NULL;
- X e->tim = CalTime;
- X }
- X
- X DoSubst(WorkBuf, TmpBuf, CurDay, CurMon, CurYear, JulianToday, tok, CalTime, 1);
- X
- X /* If the buffer contains zero-length string; forget it. */
- X if (!*TmpBuf) {
- X if (!SimpleCalendar) free(e);
- X return (NULL);
- X }
- X
- X /* If we're doing a simple calendar, just spit out the text and end */
- X if (SimpleCalendar) {
- X printf("%04d/%02d/%02d: ", CurYear, 1+CurMon, CurDay);
- X Output(TmpBuf);
- X return (NULL);
- X }
- X
- X /* Now copy from TmpBuf to WorkBuf, splitting words as needed */
- X s = TmpBuf;
- X t = WorkBuf;
- X column = 0;
- X while (*s) {
- X l = WordLen(s);
- X if (column == 0 && l >= CalWidth) {
- X CopyWord(&s, &t, CalWidth);
- X *t++ = '\n';
- X while (isspace(*s)) s++;
- X }
- X else if (column != 0 && column+l > CalWidth) {
- X *t++ = '\n';
- X column = 0;
- X if (l >= CalWidth) {
- X CopyWord(&s, &t, CalWidth);
- X *t++ = '\n';
- X while (isspace(*s)) s++;
- X } else {
- X CopyWord(&s, &t, l);
- X *t++ = ' ';
- X while (isspace(*s)) s++;
- X column = l+1;
- X if (column >= CalWidth) {
- X *(t-1) = '\n';
- X column = 0;
- X }
- X
- X }
- X }
- X else {
- X column += l+1;
- X CopyWord(&s, &t, l);
- X while (isspace(*s)) s++;
- X *t++ = ' ';
- X if (column > CalWidth) {
- X *(t-1) = '\n';
- X column = 0;
- X }
- X }
- X }
- X *t = 0;
- X if (*(t-1) == '\n') *(t-1) = 0;
- X
- X /* Finally, copy the string to the calendar entry */
- X e->text = (char *) malloc(strlen(WorkBuf)+1);
- X
- X if (!e->text) {
- X fprintf(stderr, "remind: Can't malloc memory for calendar text!\n");
- X exit(1);
- X }
- X strcpy(e->text, WorkBuf);
- X e->current = e->text;
- X
- X return e;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* EmitOneCalendarLine */
- X/* This is the biggie - we print out one line. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid EmitOneCalendarLine(void)
- X#else
- Xvoid EmitOneCalendarLine()
- X#endif
- X{
- X int i, nlines, emit, j;
- X char *s, *dst;
- X CalEntry *e;
- X char pend[7]; /* Reminders with following blanks pending */
- X
- X if (SimpleCalendar) return;
- X
- X nlines = 0;
- X for (i=0; i<7; i++) pend[i] = 0;
- X putchar('|');
- X /* First, emit the days of the month */
- X for (i=0; i<7; i++) {
- X if (!used[i]) PrintChars(CalWidth, ' ');
- X else {
- X sprintf(TmpBuf, "%d", used[i]);
- X printf(TmpBuf);
- X PrintChars(CalWidth-strlen(TmpBuf), ' ');
- X }
- X putchar('|');
- X }
- X putchar('\n');
- X
- X /* Now cycle through all the reminders until there are none left */
- X emit = 1;
- X while(emit) {
- X dst = WorkBuf;
- X *dst++ = '|';
- X emit = 0;
- X for (i=0; i<7; i++) {
- X if (pend[i] || !used[i] || !entry[i].next) {
- X dst = CopyChars(CalWidth, ' ', dst);
- X *dst++ = '|';
- X if(pend[i]) {pend[i] = 0; emit = 1;}
- X continue;
- X }
- X s = entry[i].next->current;
- X j = 0;
- X emit = 1;
- X while (*s && *s != '\n') {
- X *dst++ = *s++;
- X j++;
- X }
- X dst = CopyChars(CalWidth - j, ' ', dst);
- X if (*s == '\n') entry[i].next->current = s+1;
- X else {
- X e = entry[i].next;
- X entry[i].next = e->next;
- X free(e->text);
- X free(e);
- X if (!entry[i].next) used[i] = 0;
- X else pend[i] = 1;
- X }
- X *dst++ = '|';
- X }
- X *dst = 0;
- X if(emit) printf("%s\n", WorkBuf);
- X nlines += emit;
- X }
- X while(nlines++ < 6) printf("%s\n", WorkBuf);
- X
- X putchar('+');
- X for (i=0; i<7; i++) {
- X PrintChars(CalWidth, '-');
- X putchar('+');
- X }
- X putchar('\n');
- X for (i=0; i<7; i++) used[i] = 0;
- X}
- END_OF_FILE
- if test 13183 -ne `wc -c <'calendar.c'`; then
- echo shar: \"'calendar.c'\" unpacked with wrong size!
- fi
- # end of 'calendar.c'
- fi
- if test -f 'dorem.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dorem.c'\"
- else
- echo shar: Extracting \"'dorem.c'\" \(11579 characters\)
- sed "s/^X//" >'dorem.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#ifndef UNIX
- X#include <stdlib.h>
- X#endif
- X#include <string.h>
- X#include <ctype.h>
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X/***************************************************************/
- X/* */
- X/* int DoRem(char **s) */
- X/* */
- X/* Process a reminder. Return 0 if reminder not emitted, */
- X/* positive if emitted, or negative if in the past and */
- X/* will never be emitted. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint DoRem(char **s)
- X#else
- Xint DoRem(s)
- Xchar **s;
- X
- X#endif
- X{
- X int d, m, y, wd, cons, delta, back, omit, done, jul, once, repeat, skip;
- X int ud, um, uy; /* Date of UNTIL */
- X int uj;
- X int tim, tdelta, trep;
- X int d2, m2, y2;
- X Token tok;
- X int trigger;
- X char NeedNewToken;
- X
- X uj = ud = um = uy = d = m = y = tim = tdelta = trep = -1;
- X back = delta = repeat = cons = wd = omit = once = skip = 0;
- X
- X
- X done = 0;
- X NeedNewToken = 1;
- X while (!done) {
- X if (NeedNewToken) tok = ParseToken(s);
- X NeedNewToken = 1;
- X switch (tok.type) {
- X
- X case Until_t:
- X NeedNewToken = 0;
- X while (!done) {
- X tok = ParseToken(s);
- X switch (tok.type) {
- X case Year_t:
- X if (uy != -1) {
- X Eprint("Year duplicated in UNTIL.\n");
- X return 0;
- X }
- X uy = tok.val;
- X break;
- X
- X case Month_t:
- X if (um != -1) {
- X Eprint("Month duplicated in UNTIL.\n");
- X return 0;
- X }
- X um = tok.val;
- X break;
- X
- X case Day_t:
- X if (ud != -1) {
- X Eprint("Day duplicated in UNTIL.\n");
- X return 0;
- X }
- X ud = tok.val;
- X break;
- X
- X default:
- X done = 1; break;
- X }
- X }
- X if (uy == -1 || um == -1 || ud == -1) {
- X Eprint("Year, month and day must all be specified after UNTIL\n");
- X return 0;
- X }
- X if (CheckDate(ud, um, uy)) {
- X Eprint("Invalid date for UNTIL.\n");
- X return 0;
- X }
- X uj = Julian(ud, um, uy);
- X done = 0; break;
- X
- X case Omit_t:
- X NeedNewToken = 0;
- X while (!done) {
- X tok = ParseToken(s);
- X switch(tok.type) {
- X case WkDay_t:
- X if (omit & (1 << tok.val)) {
- X Eprint("%s duplicated.\n", tok.str);
- X return 0;
- X }
- X omit |= 1 << tok.val;
- X break;
- X
- X default: done = 1; break;
- X }
- X }
- X done = 0;
- X break;
- X
- X case At_t:
- X NeedNewToken = 0;
- X while (!done) {
- X tok = ParseToken(s);
- X switch(tok.type) {
- X
- X case Time_t:
- X if (tim != -1) {
- X Eprint("Time specified twice.\n");
- X return 0;
- X }
- X else tim = tok.val;
- X break;
- X
- X case Repeat_t:
- X if (trep != -1) {
- X Eprint("Time repeat factor specified twice.\n");
- X return 0;
- X }
- X trep = tok.val;
- X if (trep <= 0) {
- X Eprint("Invalid value for timerepeat factor: %d\n", repeat);
- X return 0;
- X }
- X break;
- X
- X case Delta_t:
- X if (tdelta != -1) {
- X Eprint("Time delta specified twice.\n");
- X return 0;
- X }
- X tdelta = ABS(tok.val);
- X break;
- X
- X default: done = 1; break;
- X }
- X }
- X done = 0; break;
- X
- X case Eol_t:
- X Eprint("Missing MSG or RUN in reminder.\n");
- X return 0;
- X
- X case Run_t:
- X case Msg_t: done = 1; break;
- X
- X case Skip_t:
- X if (skip) {
- X Eprint("Can only have one of BEFORE, AFTER or SKIP.\n");
- X return 0;
- X }
- X skip = tok.val;
- X break;
- X
- X case Unknown_t:
- X Eprint("Unknown token %s in reminder.\n", tok.str);
- X return 0;
- X
- X case Repeat_t:
- X if (repeat) {
- X Eprint("Repeat factor specified twice.\n");
- X return 0;
- X }
- X repeat = tok.val;
- X if (repeat <= 0) {
- X Eprint("Invalid value for repeat factor: %d\n", repeat);
- X return 0;
- X }
- X break;
- X
- X case WkDay_t:
- X if (wd & (1 << tok.val)) {
- X Eprint("%s duplicated.\n", tok.str);
- X return 0;
- X }
- X wd |= 1 << tok.val;
- X cons |= WKDAY_M;
- X break;
- X
- X case Year_t:
- X if (y != -1) {
- X Eprint("Year specified twice.\n");
- X return 0;
- X }
- X y = tok.val;
- X cons |= YEAR_M;
- X break;
- X
- X case Month_t:
- X if (m != -1) {
- X Eprint("Month specified twice.\n");
- X return 0;
- X }
- X m = tok.val;
- X cons |= MONTH_M;
- X break;
- X
- X case Day_t:
- X if (d != -1) {
- X Eprint("Day specified twice.\n");
- X return 0;
- X }
- X d = tok.val;
- X cons |= DAY_M;
- X break;
- X
- X case Delta_t:
- X if (delta) {
- X Eprint("Delta specified twice.\n");
- X return 0;
- X }
- X delta = tok.val;
- X break;
- X
- X case Back_t:
- X if (back) {
- X Eprint("Back specified twice.\n");
- X return 0;
- X }
- X back = tok.val;
- X break;
- X
- X case Once_t:
- X if (once) {
- X Eprint("ONCE specified twice. (How's that for an error message??)\n");
- X return 0;
- X }
- X once = 1;
- X break;
- X
- X default:
- X Eprint("Can't use token %s here.\n", tok.str);
- X return 0;
- X }
- X }
- X
- X /* Do some sanity checking on the reminder */
- X if (repeat && (d == -1 || m == -1 || y == -1)) {
- X Eprint("Can't use repeat counter unless you fully specify the date.\n");
- X return 0;
- X }
- X
- X if (skip && (wd & omit)) {
- X Eprint("Conflict between weekday list and local OMIT\n");
- X return 0;
- X }
- X
- X if (d != -1 && m != -1 && CheckDate(d, m, y)) {
- X Eprint("Illegal date specification.\n");
- X return 0;
- X }
- X if (y != -1 && (y < BASE || y > BASE + 85)) {
- X Eprint("Illegal date specification.\n");
- X return 0;
- X }
- X
- X /* Print some helpful stuff if debugging */
- X if (Debug) {
- X if (back > 7) Eprint("Warning: 'back' > 7 could slow execution severely.\n");
- X if (delta > 30 && (omit || NumFullOmit || NumPartOmit))
- X Eprint("Warning: 'delta' > 30 with OMITs could slow execution severely.\n");
- X }
- X
- X if (omit == 127) {
- X Eprint("Can't omit every day!\n");
- X return 0;
- X }
- X
- X if (IgOnce) once = 0;
- X
- X /* Check if we can quickly determine reminder is not to be emitted */
- X if (once && !Debug && !Purge && (LastRun == JulianToday)) return 0;
- X
- X /* Have we passed the UNTIL date ? */
- X if (uj != -1 && uj < JulianToday) {
- X if (Debug) Eprint("Reminder has expired.\n");
- X return -1;
- X }
- X
- X jul = GetTriggerDate(d, m, y, wd, cons, back, repeat, omit, skip);
- X if (uj != -1 && uj < jul) {
- X if (Debug) Eprint("Reminder has expired.\n");
- X return -1;
- X }
- X
- X if (Calendar) {
- X if (jul == JulianToday) {
- X while (isspace(**s)) (*s)++;
- X strcpy(WorkBuf, *s);
- X CalTime = tim;
- X if (tok.type == Run_t) return 2; else return 1;
- X } else return 0;
- X }
- X
- X if (jul == -1) {
- X if (Debug) Eprint("Reminder has expired.\n");
- X return -1;
- X } else if (jul == -2) return 0;
- X
- X FromJulian(jul, &d2, &m2, &y2);
- X
- X /* If we're in "Next" mode, output this one in simple-calendar format */
- X if (Next) {
- X DoSubst(*s, WorkBuf, d2, m2, y2, jul, tok.type, tim, 1);
- X if (!*WorkBuf) return 0;
- X printf("%04d/%02d/%02d: ", y2, m2+1, d2);
- X printf("%s\n", WorkBuf);
- X return 0;
- X }
- X
- X /* Figure out if the reminder should be triggered */
- X
- X trigger = MoveBack(jul, delta, omit);
- X
- X if(Debug) {
- X Eprint("%sTrigger date: %s, %d %s, %d.\n",
- X (trigger <= JulianToday ? "*" : ""), DayName[jul % 7],
- X d2, MonthName[m2], y2);
- X return 0;
- X }
- X if (Purge || (once && (LastRun == JulianToday))) return 0;
- X
- X while (isspace(**s)) (*s)++;
- X
- X if (trigger <= JulianToday && !(tok.type == Run_t && IgRun)) {
- X /* Trigger a reminder */
- X#ifdef UNIX
- X if (QueueAts && (jul == JulianToday) && (tim != -1)) {
- X DoAt(tim, tdelta, trep, *s, tok.type);
- X }
- X if (!PrintAts && (jul == JulianToday) && tim != -1) return 0;
- X#endif
- X if (tok.type == Msg_t) {
- X if (NumEmitted == 0) {
- X NumEmitted++;
- X DoSubst(Banner, WorkBuf, CurDay, CurMon, CurYear,
- X JulianToday, Msg_t, (int) (SystemTime()/ 60), 0);
- X printf("%s\n", WorkBuf);
- X }
- X DoSubst(*s, WorkBuf, d2, m2, y2, jul, tok.type, tim, 0);
- X printf("%s\n", WorkBuf);
- X }
- X else if (tok.type == Run_t) {
- X DoSubst(*s, WorkBuf, d2, m2, y2, jul, tok.type, tim, 0);
- X system(WorkBuf);
- X }
- X else Eprint("Error: Invalid token type %d\n", tok.type);
- X return 1;
- X } else return 0;
- X
- X}
- X
- X/***************************************************************/
- X/* */
- X/* GetTriggerDate */
- X/* */
- X/* Gets the trigger date for a reminder, returns the julian */
- X/* date, or -1 if the reminder has expired. */
- X/* Returns -2 if an error occurs. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint GetTriggerDate(int d, int m, int y, int wd, int cons, int back, int repeat, int omit, int skip)
- X#else
- Xint GetTriggerDate(d, m, y, wd, cons, back, repeat, omit, skip)
- Xint d, m, y, wd, cons, back, repeat, omit, skip;
- X#endif
- X#define MAXATTEMPTS 25 /* Maximum number of attempts before giving up */
- X
- X{
- X int i, d2, m2, y2, jul;
- X int d1, m1, y1, julstart;
- X int nattempts = 0;
- X
- X julstart = JulianToday;
- X
- X /* If we have a skip factor of 3 (AFTER), then we must back up to
- X the beginning of the block of omitted days. */
- X if (skip == 3) while(julstart>=1 && IsOmitted(julstart-1, omit)) julstart--;
- X
- X FromJulian(julstart, &d1, &m1, &y1);
- X
- X /* Make a first stab at the date */
- X i = TryNextDate(&d2, &m2, &y2, d1, m1, y1, d, m, y, wd, cons, 0);
- X if (!i || repeat) jul = Julian(d2, m2, y2);
- X
- X if (!repeat && !back && !skip) {
- X if (i) return -1; else return jul;
- X }
- X
- X if (i && !repeat) return -1;
- X
- X while (nattempts++ < MAXATTEMPTS) {
- X if (back) jul = MoveBack(jul, back, omit);
- X if (repeat) {
- X if (jul < julstart) {
- X jul += ((julstart - jul) / repeat) * repeat;
- X if (jul < julstart) jul += repeat;
- X }
- X }
- X if (skip == 2) while (IsOmitted(jul, omit)) jul--;
- X else if (skip == 3) while (IsOmitted(jul, omit)) jul++;
- X if ((skip == 1 && IsOmitted(jul, omit)) || jul < JulianToday) {
- X if (!repeat) {
- X i = TryNextDate(&d2, &m2, &y2, d2, m2, y2, d, m, y, wd, cons, 1);
- X if (i) return -1;
- X jul = Julian(d2, m2, y2);
- X } else {
- X jul += repeat;
- X back = 0; /* We've already handled the back! */
- X }
- X } else return jul;
- X }
- X Eprint("Couldn't compute a trigger date - check that date is sensible.\n");
- X return -2;
- X}
- END_OF_FILE
- if test 11579 -ne `wc -c <'dorem.c'`; then
- echo shar: \"'dorem.c'\" unpacked with wrong size!
- fi
- # end of 'dorem.c'
- fi
- if test -f 'main.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'main.c'\"
- else
- echo shar: Extracting \"'main.c'\" \(20411 characters\)
- sed "s/^X//" >'main.c' <<'END_OF_FILE'
- X/***************************************************************/
- X/* */
- X/* REMIND - version 2.3 */
- X/* */
- X/* By David Skoll - 11 February 1991 */
- X/* */
- X/* (C) 1990, 1991 by David Skoll - all rights reserved */
- X/* */
- X/***************************************************************/
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X
- X#ifndef UNIX
- X#include <stdlib.h>
- X#include <dos.h>
- X#include <stdarg.h>
- X#else
- X#include <varargs.h>
- X#include <sys/types.h>
- X#ifdef SYSV
- X#include <time.h>
- X#else
- X#include <sys/time.h>
- X#endif
- X#endif
- X
- X#include "defines.h"
- X#include "protos.h"
- X
- X
- X/* List of months */
- Xchar *MonthName[] = {
- X "January", "February", "March", "April", "May", "June",
- X "July", "August", "September", "October", "November", "December"
- X};
- X
- X/* List of weekdays */
- Xchar *DayName[] = {
- X "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
- X};
- X
- X/* List of recognized tokens - Keep them SORTED (case insensitive.) */
- X
- XToken keywd[] = {
- X { "AFTER", Skip_t, 3, 3 },
- X { "April", Month_t, 3, 3 },
- X { "AT", At_t, 0, 2 },
- X { "August", Month_t, 7, 3 },
- X { "BANNER", Banner_t, 0, 3 },
- X { "BEFORE", Skip_t, 2, 3 },
- X { "CLEAR-OMIT-CONTEXT", Clear_t, 0, 3},
- X { "December", Month_t, 11, 3 },
- X { "February", Month_t, 1, 3 },
- X { "Friday", WkDay_t, 4, 3 },
- X { "INCLUDE", Include_t, 0, 3 },
- X { "January", Month_t, 0, 3 },
- X { "July", Month_t, 6, 3 },
- X { "June", Month_t, 5, 3 },
- X { "March", Month_t, 2, 3 },
- X { "May", Month_t, 4, 3 },
- X { "Monday", WkDay_t, 0, 3 },
- X { "MSG", Msg_t, 0, 3 },
- X { "November", Month_t, 10, 3 },
- X { "October", Month_t, 9, 3 },
- X { "OMIT", Omit_t, 0, 3 },
- X { "ONCE", Once_t, 0, 3 },
- X { "POP-OMIT-CONTEXT", Pop_t, 0, 3},
- X { "PUSH-OMIT-CONTEXT", Push_t, 0, 3 },
- X { "REM", Rem_t, 0, 3 },
- X { "RUN", Run_t, 0, 3 },
- X { "Saturday", WkDay_t, 5, 3 },
- X { "September", Month_t, 8, 3 },
- X { "SKIP", Skip_t, 1, 3 },
- X { "Sunday", WkDay_t, 6, 3 },
- X { "Thursday", WkDay_t, 3, 3 },
- X { "Tuesday", WkDay_t, 1, 3 },
- X { "UNTIL", Until_t, 0, 3 },
- X { "Wednesday", WkDay_t, 2, 3 }
- X};
- X
- X/* List of days in month - Feb MUST be 29 for CheckDate to work. */
- Xint MonthDays[] = {
- X 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- X};
- X
- X/* Index of the first day of each month. First array is non-leap-year;
- X second is leap-year. */
- Xint MonthIndex[2][12] = {
- X { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
- X { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
- X};
- X
- X/* Global ommissions array */
- Xint FullOmitArray[FOMITSIZE];
- X
- X/* Global partial omissions array */
- Xint PartOmitArray[POMITSIZE];
- X
- X/* Define the working buffers */
- Xchar Line[512], WorkBuf[512];
- Xchar TmpBuf[512];
- Xchar Fresh; /* True if the contents of Line are fresh */
- X
- X/* Global variables */
- Xchar Purge, Debug, Verbose, IgRun, IgOnce, Next;
- Xint LastRun;
- Xchar FileName[200];
- Xint CurLine;
- Xchar Banner[200] = "Reminders for %w, %d%s %m, %y%o:";
- Xint NumEmitted, NumRem;
- Xint NumFullOmit, NumPartOmit;
- Xint JulianToday, RealToday;
- Xint CurYear, CurMon, CurDay;
- Xchar QueueAts, PrintAts;
- Xint NumAtsQueued;
- Xint Calendar, CalTime, CalWidth, SimpleCalendar;
- X
- Xstatic int JulFirst; /* Julian date of 1 Jan Current_year */
- Xstatic int FirstYear;
- X
- X/***************************************************************/
- X/* */
- X/* Output */
- X/* Output a string with line separators. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid Output(char *s)
- X#else
- Xvoid Output(s)
- Xchar *s;
- X#endif
- X{
- X while (*s) {
- X if (*s == '\n') putchar('\\');
- X putchar(*s++);
- X }
- X putchar('\n');
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int MoveBack(...) */
- X/* */
- X/* Move back by specified number of days, skipping holidays */
- X/* if the amound to move back is positive; otherwise, just */
- X/* move back (-back) days, ignoring holidays. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint MoveBack (int jul, int back, int omit)
- X#else
- Xint MoveBack (jul, back, omit)
- X int jul;
- X int back;
- X int omit;
- X#endif
- X{
- X if (back <= 0) return jul+back;
- X
- X if (!NumFullOmit && !NumPartOmit && !omit) return jul - back;
- X while (back) {
- X jul--;
- X if (!IsOmitted(jul, omit)) back--;
- X }
- X return jul;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int ProcessLine() */
- X/* */
- X/* Process the line in the "Line" buffer. */
- X/* */
- X/* Normally returns 0. Returns 1 only if we're in Calendar */
- X/* mode and we hit a reminder which should be placed in the */
- X/* calendar. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint ProcessLine(void)
- X#else
- Xint ProcessLine()
- X#endif
- X{
- X char *s = Line;
- X Token tok;
- X int i;
- X
- X while (isspace(*s)) s++;
- X
- X /* Skip comments and blank lines */
- X if (*s == '#' || *s == 0) {
- X if (Purge && TopLevel()) Output(Line);
- X return 0;
- X }
- X
- X tok = ParseToken(&s);
- X switch(tok.type) {
- X case Push_t: PushOmitContext();
- X if (Purge && TopLevel()) Output(Line);
- X break;
- X
- X case Pop_t: PopOmitContext();
- X if (Purge && TopLevel()) Output(Line);
- X break;
- X
- X case Clear_t: ClearOmitContext();
- X if (Purge && TopLevel()) Output(Line);
- X break;
- X
- X case Banner_t: DoBanner(&s);
- X if (Purge && TopLevel()) Output(Line);
- X break;
- X
- X case Omit_t: i = DoGlobalOmit(&s);
- X if (Calendar) return i;
- X if (Purge && TopLevel())
- X if (i == -1) Eprint("Purged '%s'\n", Line);
- X else Output(Line);
- X break;
- X
- X case Rem_t: i = DoRem(&s);
- X if (Calendar) return i;
- X if (Purge && TopLevel())
- X if (i < 0) Eprint("Purged '%s'\n", Line);
- X else Output(Line);
- X NumRem++;
- X break;
- X
- X case Include_t: if (Purge && TopLevel()) Output(Line);
- X DoInclude(&s);
- X break;
- X
- X default: if (Purge && TopLevel()) Output(Line);
- X Eprint("Unknown command '%s'\n", tok.str);
- X }
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* Standard: void Eprint(const char *f, ...) */
- X/* Unix: void Eprint(va_alist) */
- X/* */
- X/* Prints an error message. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xvoid Eprint(const char *f, ...)
- X#else
- X/*VARARGS0*/
- Xvoid Eprint(va_alist)
- Xva_dcl
- X#endif
- X{
- X#ifndef UNIX
- X va_list args;
- X#else
- X va_list args;
- X char *f;
- X#endif
- X
- X#ifndef UNIX
- X if (Verbose & Fresh) {
- X#else
- X if (Verbose & Fresh) {
- X#endif
- X fprintf(stderr, "\n--- %s\n", Line);
- X Fresh = 0;
- X }
- X if (Verbose) fprintf(stderr, "--- ");
- X fprintf(stderr, "%s(%d): ", FileName, CurLine);
- X#ifndef UNIX
- X va_start(args, f);
- X#else
- X va_start(args);
- X f = va_arg(args, char *);
- X#endif
- X vfprintf(stderr, f, args);
- X#ifdef UNIX
- X va_end(args);
- X#endif
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int DoBanner(char **s) */
- X/* */
- X/* Sets the "Reminders for..." banner. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint DoBanner(char **s)
- X#else
- Xint DoBanner(s)
- X char **s;
- X#endif
- X{
- X if (Purge || Next) return 0;
- X while (isspace(**s)) (*s)++;
- X strcpy(Banner, *s);
- X if (! *Banner)
- X {
- X if (Debug) Eprint("Empty banner.\n");
- X strcpy(Banner, "Reminders for %w, %d%s %m, %y%o:");
- X }
- X if (NumRem && Debug) Eprint("Warning: Banner after reminder.\n");
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int CheckDate(int d, int m, int y) */
- X/* */
- X/* Checks that a date is valid - returns 0 for OK, 1 for BAD. */
- X/* */
- X/* If y=-1, just checks that month & day are valid, giving */
- X/* benefit of the doubt for February 29. */
- X/* */
- X/* No point in checking if month is valid - months are named */
- X/* and thus a month out of range can never be entered into */
- X/* the system. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint CheckDate(int d, int m, int y)
- X#else
- Xint CheckDate(d, m, y)
- X int d;
- X int m;
- X int y;
- X#endif
- X{
- X if (y == -1)
- X if (d > 0 && d <= MonthDays[m]) return 0; else return 1;
- X else
- X if (y < BASE || y > BASE + 85) return 1;
- X else if (d > 0 && d <= DaysInMonth(m, y)) return 0; else return 1;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int strncmpi(char *s1, char*s1, int n) */
- X/* */
- X/* Compares first n chars of string ignoring case. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint strncmpi(char *s1, char *s2, int n)
- X#else
- Xint strncmpi(s1, s2, n)
- X char *s1;
- X char *s2;
- X int n;
- X#endif
- X{
- X register int u1, u2;
- X while (n)
- X {
- X if (!*s1 || !*s2) return upper(*s1) - upper(*s2);
- X u1 = upper(*s1);
- X u2 = upper(*s2);
- X if (u1 != u2) return (u1 - u2);
- X n--;
- X s1++;
- X s2++;
- X }
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* ParseToken(char **s); */
- X/* */
- X/* Parse the next token and adjust the character pointer. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- XToken ParseToken(char **s)
- X#else
- XToken ParseToken(s)
- X char **s;
- X#endif
- X{
- X
- X Token tok;
- X char *t = TmpBuf;
- X int i, h, m;
- X int len;
- X int top, bot, mid;
- X char *colon = (char *) NULL;
- X
- X *t = 0;
- X tok.str = TmpBuf;
- X
- X /* Skip blank space */
- X while (isspace(**s)) (*s)++;
- X
- X /* End of line ? */
- X if (**s == 0) {
- X tok.type = Eol_t;
- X tok.val = 0;
- X return tok;
- X }
- X
- X /* Grab a space-delimited token */
- X while (**s != 0 && !isspace(**s)) {
- X *t++ = **s;
- X (*s)++;
- X }
- X *t = 0;
- X len = t - TmpBuf;
- X
- X /* Check if it's a built-in token */
- X if (*TmpBuf >= 'A' && *TmpBuf <= 'z') {
- X top = sizeof(keywd)/sizeof(keywd[0])-1;
- X bot = 0;
- X mid = (top+bot)/2;
- X while (top >= bot &&
- X (i=strncmpi(TmpBuf, keywd[mid].str, MAX(len, (int) keywd[mid].len)))) {
- X if (i>0) bot = mid+1; else top = mid-1;
- X mid = (top+bot)/2;
- X }
- X if (top >= bot) return keywd[mid];
- X }
- X
- X tok.type = Unknown_t;
- X
- X /* If it's a comment, ignore the rest of the line */
- X if (*(tok.str) == '#') {
- X tok.type = Eol_t;
- X return tok;
- X }
- X
- X /* Check if it's a number (optional + / - / * ahead of number */
- X t = TmpBuf;
- X i = 1; /* multiplication factor */
- X if (isdigit(*t)) {
- X while (*++t){
- X if (*t == ':') {
- X if (colon) return tok; else colon = t;
- X } else if (!isdigit(*t)) return tok;
- X }
- X }
- X else if (*t == '+' || *t == '-' || *t == '*') {
- X /* Check if it's a "++" or a "--" */
- X if ((*t == '+' && *(t+1) == '+') || (*t == '-' && *(t+1) == '-')) {
- X i = -1;
- X t++;
- X }
- X if (!isdigit(*++t)) return tok;
- X while (*++t) if (!isdigit(*t)) return tok;
- X }
- X else return tok;
- X
- X /* OK, here we have a number - either a pure number, a delta, a time,
- X back or a repeat marker */
- X
- X if (colon) { /* got a time here */
- X h = atoi(TmpBuf);
- X m = atoi(colon + 1);
- X if (h >= 0 && h <= 23 && m >= 0 && m <= 59) {
- X tok.type = Time_t;
- X tok.val = 60*h+m;
- X }
- X else return tok;
- X }
- X else if (*TmpBuf == '+') {
- X tok.type = Delta_t;
- X if (i == 1) tok.val = atoi(TmpBuf + 1);
- X else tok.val = -atoi(TmpBuf + 2);
- X }
- X else if (*TmpBuf == '-') {
- X tok.type = Back_t;
- X if (i == 1) tok.val = atoi(TmpBuf + 1);
- X else tok.val = -atoi(TmpBuf + 2);
- X }
- X else if (*TmpBuf == '*') {
- X tok.type = Repeat_t;
- X tok.val = atoi(TmpBuf + 1);
- X }
- X else {
- X tok.val = atoi(TmpBuf);
- X if (tok.val > 0 && tok.val <= 31) tok.type = Day_t;
- X else if (tok.val >= 100) tok.type = Year_t;
- X else {
- X tok.type = Year_t;
- X tok.val += 1900;
- X }
- X }
- X return tok;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int FromJulian(int jul, int *d, int *m, int *y) */
- X/* */
- X/* Convert a date from Julian to normal form. Returns */
- X/* 0 if conversion ok, -1 otherwise. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint FromJulian(int jul, int *d, int *m, int *y)
- X#else
- Xint FromJulian(jul, d, m, y)
- X int jul;
- X int *d;
- X int *m;
- X int *y;
- X#endif
- X{
- X int t;
- X
- X if (jul < 0) return -1;
- X
- X if (jul >= JulFirst && JulFirst != -1) {
- X *y = FirstYear;
- X jul -= JulFirst;
- X } else *y = BASE;
- X
- X *m = 0;
- X
- X t = DaysInYear(*y);
- X while (jul >= t) {
- X jul -= t;
- X (*y)++;
- X t = DaysInYear(*y);
- X }
- X
- X t = DaysInMonth(*m, *y);
- X while (jul >= t) {
- X jul -= t;
- X (*m)++;
- X t = DaysInMonth(*m, *y);
- X }
- X *d = jul + 1;
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int Julian(d, m, y) */
- X/* */
- X/* Converts a date to the number of days after Jan 1 1990. */
- X/* Returns -1 if date is before Jan 1 1990. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint Julian(int d, int m, int y)
- X#else
- Xint Julian(d, m, y)
- X int d;
- X int m;
- X int y;
- X#endif
- X{
- X int iy;
- X int jul = 0;
- X
- X if (y < BASE) return -1;
- X if (JulFirst == -1 || y < FirstYear)
- X for (iy = BASE; iy < y; iy++) jul += DaysInYear(iy);
- X else {
- X jul = JulFirst;
- X for (iy = FirstYear; iy < y; iy++) jul += DaysInYear(iy);
- X }
- X
- X return jul + MonthIndex[IsLeapYear(y)][m] + d - 1;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int FindTodaysDate(int *d, int *m, int *y) */
- X/* */
- X/* Obtains today's date. Returns Julian date or -1 for */
- X/* failure. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint FindTodaysDate(int *d, int *m, int *y)
- X#else
- Xint FindTodaysDate(d, m, y)
- X int *d;
- X int *m;
- X int *y;
- X#endif
- X{
- X#ifndef UNIX
- X struct dosdate_t buf;
- X
- X _dos_getdate(&buf);
- X
- X *d = buf.day;
- X *m = buf.month - 1;
- X *y = buf.year;
- X#else
- X time_t tloc;
- X struct tm *t;
- X
- X (void) time(&tloc);
- X t = localtime(&tloc);
- X
- X *d = t->tm_mday;
- X *m = t->tm_mon;
- X *y = t->tm_year + 1900;
- X
- X#endif
- X if (CheckDate(*d, *m, *y)) return -1;
- X return Julian(*d, *m, *y);
- X}
- X/***************************************************************/
- X/***************************************************************/
- X/** **/
- X/** MAIN PROGRAM ENTRY POINT **/
- X/** **/
- X/***************************************************************/
- X/***************************************************************/
- X#ifdef __STDC__
- Xint main(int argc, char *argv[])
- X#else
- Xint main(argc, argv)
- X int argc;
- X char *argv[];
- X#endif
- X{
- X#ifdef UNIX
- X#ifdef SYSV
- X pid_t pid;
- X#else
- X int pid;
- X#endif
- X#endif
- X
- X NumEmitted = 0;
- X NumRem = 0;
- X JulFirst = -1; /* Initialize JulFirst so it's not used by Julian */
- X
- X JulianToday = FindTodaysDate(&CurDay, &CurMon, &CurYear);
- X if (JulianToday < 0) {
- X fprintf(stderr, "remind: System date is illegal - Ensure that year is at least %d.\n", BASE);
- X return 1;
- X }
- X
- X RealToday = JulianToday;
- X
- X initialize(argc, argv);
- X
- X FirstYear = CurYear;
- X JulFirst = Julian(1, 0, CurYear); /* Do expensive computation once */
- X FirstYear = CurYear;
- X
- X if (Calendar) {
- X DoCalendar();
- X return 0;
- X }
- X while (1) {
- X if (ReadLine()) break;
- X ProcessLine();
- X }
- X/* Get rid of any spurious OMIT contexts */
- X FreeStackedOmits();
- X if (NumEmitted == 0 && NumAtsQueued == 0 && !Purge && !Debug && !Next)
- X printf("No reminders.\n");
- X#ifdef UNIX
- X if (NumEmitted == 0 && NumAtsQueued != 0 && !Purge && !Debug)
- X printf("%d reminder%s queued for later today.\n", NumAtsQueued,
- X (NumAtsQueued == 1) ? "" : "s");
- X
- X fflush(stdout); /* Flush output so we don't get 2 copies when directing */
- X /* stdout to a file. */
- X
- X if (NumAtsQueued) {
- X pid = fork();
- X if (pid == -1) Eprint("Can't fork to perform ATs!\n");
- X if (pid != 0) return 0;
- X HandleQueuedAts();
- X }
- X#endif
- X return 0;
- X}
- X/***************************************************************/
- X/* */
- X/* SystemTime */
- X/* */
- X/* Returns current system time in seconds past midnight. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xlong SystemTime(void)
- X#else
- Xlong SystemTime()
- X#endif
- X{
- X#ifdef UNIX
- X time_t tloc;
- X struct tm *t;
- X
- X (void) time(&tloc);
- X t = localtime(&tloc);
- X return (long) t->tm_hour * 3600L + (long) t->tm_min * 60L + (long) t->tm_sec;
- X
- X#else
- X struct dostime_t tloc;
- X _dos_gettime(&tloc);
- X return (long) tloc.hour * 3600L + (long) tloc.minute * 60L + (long) tloc.second;
- X#endif
- X}
- END_OF_FILE
- if test 20411 -ne `wc -c <'main.c'`; then
- echo shar: \"'main.c'\" unpacked with wrong size!
- fi
- # end of 'main.c'
- fi
- if test -f 'test.out' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'test.out'\"
- else
- echo shar: Extracting \"'test.out'\" \(6464 characters\)
- sed "s/^X//" >'test.out' <<'END_OF_FILE'
- X
- XFile test.rem last accessed on Tuesday, 19 February, 1991
- X
- X--- REM MSG Every Day
- X--- test.rem(19): *Trigger date: Saturday, 16 February, 1991.
- X
- X--- REM 18 MSG Every 18th
- X--- test.rem(21): Trigger date: Monday, 18 February, 1991.
- X
- X--- REM 15 MSG Every 15th
- X--- test.rem(22): Trigger date: Friday, 15 March, 1991.
- X
- X--- REM Feb MSG February
- X--- test.rem(24): *Trigger date: Saturday, 16 February, 1991.
- X
- X--- REM Jan MSG January
- X--- test.rem(25): Trigger date: Wednesday, 1 January, 1992.
- X
- X--- REM March MSG March
- X--- test.rem(26): Trigger date: Friday, 1 March, 1991.
- X
- X--- REM 13 Jan MSG 13 Jan
- X--- test.rem(28): Trigger date: Monday, 13 January, 1992.
- X
- X--- REM 15 Feb MSG 15 Feb
- X--- test.rem(29): Trigger date: Saturday, 15 February, 1992.
- X
- X--- REM 28 Feb MSG 28 Feb
- X--- test.rem(30): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 29 Feb MSG 29 Feb
- X--- test.rem(31): Trigger date: Saturday, 29 February, 1992.
- X
- X--- REM 5 Mar MSG 5 Mar
- X--- test.rem(32): Trigger date: Tuesday, 5 March, 1991.
- X
- X--- REM 1990 MSG 1990
- X--- test.rem(34): Reminder has expired.
- X
- X--- REM 1991 MSG 1991
- X--- test.rem(35): *Trigger date: Saturday, 16 February, 1991.
- X
- X--- REM 1992 MSG 1991
- X--- test.rem(36): Trigger date: Wednesday, 1 January, 1992.
- X
- X--- REM 1 1990 MSG 1 1990
- X--- test.rem(38): Reminder has expired.
- X
- X--- REM 29 1991 MSG 29 1991
- X--- test.rem(39): Trigger date: Friday, 29 March, 1991.
- X
- X--- REM 29 1992 MSG 29 1992
- X--- test.rem(40): Trigger date: Wednesday, 29 January, 1992.
- X
- X--- REM 16 1991 MSG 16 1991
- X--- test.rem(41): *Trigger date: Saturday, 16 February, 1991.
- X
- X--- REM Jan 1990 MSG Jan 1990
- X--- test.rem(43): Reminder has expired.
- X
- X--- REM Feb 1991 MSG Feb 1991
- X--- test.rem(44): *Trigger date: Saturday, 16 February, 1991.
- X
- X--- REM Dec 1991 MSG Dec 1991
- X--- test.rem(45): Trigger date: Sunday, 1 December, 1991.
- X
- X--- REM May 1992 MSG May 1992
- X--- test.rem(46): Trigger date: Friday, 1 May, 1992.
- X
- X--- REM 1 Jan 1991 MSG 1 Jan 1991
- X--- test.rem(48): Reminder has expired.
- X
- X--- REM 16 Feb 1991 MSG 16 Feb 1991
- X--- test.rem(49): *Trigger date: Saturday, 16 February, 1991.
- X
- X--- REM 29 Dec 1992 MSG 29 Dec 1992
- X--- test.rem(50): Trigger date: Tuesday, 29 December, 1992.
- X
- X--- REM Sun MSG Sun
- X--- test.rem(52): Trigger date: Sunday, 17 February, 1991.
- X
- X--- REM Fri Sat Tue MSG Fri Sat Tue
- X--- test.rem(53): *Trigger date: Saturday, 16 February, 1991.
- X
- X--- REM Sun 16 MSG Sun 16
- X--- test.rem(55): Trigger date: Sunday, 17 February, 1991.
- X
- X--- REM Mon Tue Wed Thu Fri 1 MSG Mon Tue Wed Thu Fri 1
- X--- test.rem(56): Trigger date: Friday, 1 March, 1991.
- X
- X--- REM Sun Feb MSG Sun Feb
- X--- test.rem(58): Trigger date: Sunday, 17 February, 1991.
- X
- X--- REM Mon Tue March MSG Mon Tue March
- X--- test.rem(59): Trigger date: Monday, 4 March, 1991.
- X
- X--- REM Sun 16 Feb MSG Sun 16 Feb
- X--- test.rem(61): Trigger date: Sunday, 17 February, 1991.
- X
- X--- REM Mon Tue 10 March MSG Mon Tue 10 March
- X--- test.rem(62): Trigger date: Monday, 11 March, 1991.
- X
- X--- REM Sat Sun 1991 MSG Sat Sun 1991
- X--- test.rem(64): *Trigger date: Saturday, 16 February, 1991.
- X
- X--- REM Mon Tue 1992 MSG Mon Tue 1992
- X--- test.rem(65): Trigger date: Monday, 6 January, 1992.
- X
- X--- REM Sun 16 1991 MSG Sun 16 1991
- X--- test.rem(67): Trigger date: Sunday, 17 February, 1991.
- X
- X--- REM Mon Tue Wed Thu Fri 1 1992 MSG Mon Tue Wed Thu Fri 1 1992
- X--- test.rem(68): Trigger date: Wednesday, 1 January, 1992.
- X
- X--- REM Mon Feb 1991 MSG Mon Feb 1991
- X--- test.rem(70): Trigger date: Monday, 18 February, 1991.
- X
- X--- REM Tue Jan 1992 MSG Tue Jan 1992
- X--- test.rem(71): Trigger date: Tuesday, 7 January, 1992.
- X
- X--- REM Sun Mon 16 Feb 1991 MSG Sun Mon 16 Feb 1991
- X--- test.rem(73): Trigger date: Sunday, 17 February, 1991.
- X
- X--- REM Tue 28 Jan 1992 MSG Tue 28 Jan 1992
- X--- test.rem(74): Trigger date: Tuesday, 28 January, 1992.
- X
- X--- REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun
- X--- test.rem(78): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun
- X--- test.rem(79): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun (28 Feb omitted)
- X--- test.rem(82): Trigger date: Wednesday, 27 February, 1991.
- X
- X--- REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun (28 Feb omitted)
- X--- test.rem(83): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM Wed UNTIL 21 Feb 1991 MSG Wed UNTIL 21 Feb 1991
- X--- test.rem(88): Trigger date: Wednesday, 20 February, 1991.
- X
- X--- REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
- X--- test.rem(93): Trigger date: Wednesday, 27 February, 1991.
- X
- X--- REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
- X--- test.rem(94): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
- X--- test.rem(95): Trigger date: Wednesday, 27 February, 1991.
- X
- X--- REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
- X--- test.rem(96): Trigger date: Friday, 28 February, 1992.
- X
- X--- REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
- X--- test.rem(97): Trigger date: Friday, 1 March, 1991.
- X
- X--- REM 1 Mar -1 MSG 1 mar -1
- X--- test.rem(101): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 1 Mar --1 MSG 1 mar --1
- X--- test.rem(102): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 28 Feb BEFORE MSG 28 Feb BEFORE
- X--- test.rem(103): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 28 Feb SKIP MSG 28 Feb SKIP
- X--- test.rem(104): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 28 Feb AFTER MSG 28 Feb AFTER
- X--- test.rem(105): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
- X--- test.rem(108): Trigger date: Wednesday, 27 February, 1991.
- X
- X--- REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
- X--- test.rem(109): Trigger date: Thursday, 28 February, 1991.
- X
- X--- REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
- X--- test.rem(110): Trigger date: Wednesday, 27 February, 1991.
- X
- X--- REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
- X--- test.rem(111): Trigger date: Friday, 28 February, 1992.
- X
- X--- REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
- X--- test.rem(112): Trigger date: Friday, 1 March, 1991.
- X
- X--- REM 13 March 1991 *1 UNTIL 19 March 1991 MSG 13-19 Mar 91
- X--- test.rem(115): Trigger date: Wednesday, 13 March, 1991.
- X
- X--- REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1
- X--- test.rem(119): Trigger date: Monday, 18 February, 1991.
- X
- X--- REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1 (17Feb91 omitted)
- X--- test.rem(122): *Trigger date: Monday, 18 February, 1991.
- X
- X--- REM 18 Feb 1991 ++1 MSG 18 Feb 1991 ++1 (17Feb91 omitted)
- X--- test.rem(123): Trigger date: Monday, 18 February, 1991.
- END_OF_FILE
- if test 6464 -ne `wc -c <'test.out'`; then
- echo shar: \"'test.out'\" unpacked with wrong size!
- fi
- # end of 'test.out'
- fi
- echo shar: End of archive 2 \(of 4\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-